package com.bianmaba.spring.security.basic.handler;

import com.bianmaba.spring.security.util.ResponseUtil;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: bianmaba-web-framework-extends
 * @description:
 * @author: Chenjiabin
 * @create: 2018-04-22 20:29
 **/
@ConditionalOnMissingBean({BianmabaAuthenticationFailureHandler.class})
public class BianmabaAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(BianmabaSessionInformationExpiredStrategy.class);


    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        String requestType = request.getHeader("request_type");
        if ("ajax".equals(requestType)) {
            writeJson(request, response, exception);
        } else {
            super.onAuthenticationFailure(request, response, exception);
        }
    }

    /**
     * 处理用户验证错误的错误信息并将信息以JSON方式写入到Response
     *
     * @param request
     * @param response
     * @param e
     * @throws IOException
     * @throws ServletException
     */
    public void writeJson(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        String resultStr = null;

        if (e.getClass().isAssignableFrom(BadCredentialsException.class)) {
            resultStr = "登录失败，用户名或密码错误，请检查用户名密码是否输入正确，键盘大写锁定状态！";
        } else if (e.getClass().isAssignableFrom(AccountExpiredException.class)) {
            resultStr = "登录失败，用户帐号已经过期，请联系管理员！";
        } else if (e.getClass().isAssignableFrom(AuthenticationCredentialsNotFoundException.class)) {
            resultStr = "登录失败，用户帐号证书不存在，请联系管理员！";
        } else if (e.getClass().isAssignableFrom(AuthenticationCredentialsNotFoundException.class)) {
            resultStr = "登录失败，用户帐号证书过期，请联系管理员！";
        } else if (e.getClass().isAssignableFrom(LockedException.class)) {
            resultStr = "登录失败，用户帐号已被锁定，请联系管理员！";
        } else if (e.getClass().isAssignableFrom(DisabledException.class)) {
            resultStr = "登录失败，用户帐号已被禁用，请联系管理员！";
        } else if (e.getClass().isAssignableFrom(AccountStatusException.class)) {
            resultStr = "登录失败，用户帐号状态异常，请联系管理员！";
        }
        Map<String, Object> result = new HashMap<String, Object>(0);
        result.put("success", false);
        result.put("status", 401);
        result.put("statusText", e.getLocalizedMessage());
        result.put("SecurityMessage", true);
        result.put("result", resultStr);
        result.put("failureType", e.getClass().getSimpleName());
        result.put("exception", ExceptionUtils.getStackTrace(e));
        ResponseUtil.writeJson(response, result, 401);
        LOGGER.error(result.get("result").toString(), e);
    }
}
